package Worker;

import Module.RegistryService;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Random;

/*
 * Exposed service of security and registration  
 */
public class RegistryInfo extends UnicastRemoteObject 
			implements RegistryService {
    private String ciphertext;
    private ArrayList<String> authCodes;
    private float cost;

    public RegistryInfo(String password, float cost) throws RemoteException {
        super();

        this.authCodes = new ArrayList<String>();
        this.ciphertext = Md5Encryption(password);
        this.cost = cost;
    }

    /*
     * Security: Validate the authentication code passed from master
     */
    public boolean verifyAuthCode(String authCode) {
        boolean result = false;
        for(String str : authCodes) {
            if(str.equals(authCode)){
                result = true;
                break;
            }
        }

        return result;
    }

    /*
     * Security: Ensure password returned by master is same as own password
     */
    public String authenticate(String password) throws RemoteException{
        String result = null;
        if(password.equals(ciphertext)) {
            // produce a random M5 code to provide authentication
            // in future method call
            Random seed = new Random();

            int random = seed.nextInt();

            System.out.println("Auth Code :" + Integer.toString(random));
            result = Md5Encryption(Integer.toString(random));

            authCodes.add(result);
        }
        return result;
    }

    public void logoff(String authCode){
        authCodes.remove(authCode);
    }

    /*
     * Custom MD5 security
     */
    private static String Md5Encryption(String plainText ) {
        String ciphertext = "";
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            md5.update(plainText.getBytes());

            byte b[] = md5.digest();
            int i;

            StringBuffer buffer = new StringBuffer("");
            for(int element : b) {
                i = element;
                if( i < 0) {
                    i += 256;
                }
                if( i < 16){
                    buffer.append("0");
                }
                buffer.append(Integer.toHexString(i));
            }

            // 32 bit code
            System.out.println("result: " + buffer.toString());

            // 16 bits code
            System.out.println("result: " + buffer.toString().substring(8,24));

            ciphertext = buffer.toString().substring(8,24);

        } catch (NoSuchAlgorithmException e) {

            e.printStackTrace();
        }
        return ciphertext;
    }

	public float getCost() {
		return cost;
	}
}
